#include <iostream>

#include "redis_client.h"
// sysctl -w kernel.core_pattern=/var/crash/core.%u.%e.%p

void TEST_1() {
  hiredis::RedisCmdArgs vec;
  vec.push_back("set");
  vec.push_back("key");
  vec.push_back("value");

  std::string str;
  hiredis::RedisClient::SerializeRedisCommand(vec, &str);
  // printf("%s\n", str.c_str());

  hiredis::RedisClient redis_client;
  rocksdb::Status s = redis_client.Connect("127.0.0.1", 6379, "");
  assert(s.ok());

  for (int i = 0; i < 1; i++) {
    // redis_client.SetCommnd("key", "value");
    s = redis_client.Send(&str);
    // s = redis_client.Send();
    assert(s.ok());
  }

  for (int i = 0; i < 1; i++) {
    hiredis::RedisReplyArgv redis_argv;
    s = redis_client.Recv(redis_argv);
    assert(s.ok());

    for (int i = 0; i < redis_argv.size(); i++) {
    }
  }
}

bool SetCommandCallback(const std::shared_ptr<zrpc::TcpConnection>& conn,
                        const hiredis::RedisReplyArgv& argv,
                        const std::any& privdata) {
  for (const auto& result : argv) {
    assert(result->type == hiredis::REDIS_REPLY_STRING && result->str == "OK");
  }
  return true;
}

bool GetCommandCallback(const std::shared_ptr<zrpc::TcpConnection>& conn,
                        const hiredis::RedisReplyArgv& argv,
                        const std::any& privdata) {
  for (const auto& result : argv) {
    assert(result->type == hiredis::REDIS_REPLY_STRING);
    assert(result->str == "value");
  }
  return true;
}

int main() {
  std::set<std::string> cluster_set;
  cluster_set.insert("127.0.0.1:6379");
  std::shared_ptr<hiredis::Hiredis> hiredis(new hiredis::Hiredis(cluster_set));
  hiredis->ClusterAllConnect();

  std::shared_ptr<hiredis::RedisAsyncClient> redis_async_client =
      hiredis->GetRedisAsyncClient("127.0.0.1:6379");
  assert(redis_async_client);

  int test_set_get_count = 1000000;

  for (int i = 0; i < test_set_get_count; i++) {
    assert(
        hiredis
            ->SetCommnd(std::to_string(i), "value",
                        std::bind(SetCommandCallback, std::placeholders::_1,
                                  std::placeholders::_2, std::placeholders::_3),
                        nullptr, redis_async_client)
            .ok());

    assert(hiredis
               ->GetCommand(
                   std::to_string(i),
                   std::bind(GetCommandCallback, std::placeholders::_1,
                             std::placeholders::_2, std::placeholders::_3),
                   nullptr, redis_async_client)
               .ok());
  }

  hiredis->Run();
}
